<?php

namespace app\common\component;

use think\Config;
use think\Cookie;
use app\web\mongo\BackendUser;

/**
 * 登录状态验证与登录、登出校验
 * Class Authentication
 * @package app\common\component
 */
class Authentication
{
    /** @var string 登录状态cookie */
    private $session_cookie_name = 'lcm_phpsession_id';
    /** @var string 唯一标识符 */
    private $token = 'lcm_user_token';

    /** 加密 */
    private function encrypt($str, $key)
    {
        return openssl_encrypt($str, 'AES-128-ECB', $key);
    }

    /** 解密 */
    private function decrypt($str, $key)
    {
        return openssl_decrypt($str, 'AES-128-ECB', $key);
    }

    /** 用户登录，设置登录cookie */
    public function login($backendUser)
    {
        // 设置用户token, logintime
        $logintime = time();
        $token = $this->encrypt($backendUser['id'] . $logintime, Config::get('authentication_cookie.token_salt'));
        $session_cookie = json_encode(['id' => $backendUser['id'], 'logintime' => $logintime, 'token' => $token]);
        $session_cookie = base64_encode($this->encrypt($session_cookie, Config::get('authentication_cookie.cookie_salt')));
        $res = BackendUser::getInstance()->update(['token' => $token, 'logintime' => $logintime], ['id' => $backendUser['id']]);
        if ($res) {
            Cookie::set($this->session_cookie_name, $session_cookie, ['httponly' => true, 'expire' => 86400]);
            Cookie::set($this->token, $token, ['httponly' => true, 'expire' => 86400]);
            return true;
        } else {
            return false;
        }
    }

    /** 登出 */
    public function logout($backendUser = [])
    {
        if ($backendUser) {
            BackendUser::getInstance()->update(['token' => ''], ['id' => $backendUser['id']]);
        }
        Cookie::set($this->session_cookie_name, null);
        Cookie::set($this->token, null);
    }

    /** 登录状态验证 */
    public function loginVerify()
    {
        $session_cookie = Cookie::get($this->session_cookie_name);
        $token = Cookie::get($this->token);
        if (empty($session_cookie) || empty($token)) {
            return false;
        }

        $token = $this->decrypt($token, Config::get('authentication_cookie.token_salt'));
        $session_cookie = base64_decode($session_cookie);
        $session_cookie = $session_cookie ? $this->decrypt($session_cookie, Config::get('authentication_cookie.cookie_salt')) : false;
        $session_cookie = $session_cookie ? json_decode($session_cookie, true) : false;
        if (empty($token) || empty($session_cookie)) {
            $this->logout();
            return false;
        }

        if ($session_cookie['id'] . $session_cookie['logintime'] != $token) {
            $this->logout();
            return false;
        }

        $backendUser = BackendUser::getInstance()->find(['id' => $session_cookie['id']]);
        if (empty($backendUser) || $backendUser['token'] != $session_cookie['token']) {
            $this->logout();
            return false;
        }

        return $backendUser;
    }
}